import requests
import time
import base64
import json    # 用于返回结果处理
from hashlib import md5
from Crypto.Cipher import AES

# 定义请求信息
url = 'https://dict.youdao.com/webtranslate'
key_url = 'https://dict.youdao.com/webtranslate/key'
headers = {
    'user-agent' : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36'
}
# 时间戳
mysticTime = int(time.time() * 1000)
def func_md5(sign_string):
    md5_decode = md5()
    md5_decode.update(sign_string.encode(encoding='utf-8'))
    return md5_decode.hexdigest()

key_string = f'client=fanyideskweb&mysticTime={mysticTime}&product=webfanyi&key=yU5nT5dK3eZ1pI4j'
# 得到key接口请求里的sign签名
key_sign = func_md5(key_string)
key_params = {
    "keyid": "webfanyi-key-getter-2025",
    "sign": key_sign,
    "client": "fanyideskweb",
    "product": "webfanyi",
    "appVersion": "1.0.0",
    "vendor": "web",
    "pointParam": "client,mysticTime,product",
    "mysticTime": mysticTime,
    "keyfrom": "fanyi.web",
    "mid": "1",
    "screen": "1",
    "model": "1",
    "network": "wifi",
    "abtest": "0",
    "yduuid": "abcdefg"
}

key_res = requests.get(key_url,headers=headers,params=key_params)
key_json = key_res.json()
key = key_json['data']['secretKey']
sign_string = f'client=fanyideskweb&mysticTime={mysticTime}&product=webfanyi&key={key}'
# 得到翻译接口请求里的sign
sign = func_md5(sign_string)
i_value = input('输入中文返回英文翻译结果：')
data = {
    "i": i_value,
    "from": "zh-CHS",
    "to": "en",
    "useTerm": "false",
    "domain": "0",
    "dictResult": "true",
    "keyid": "webfanyi",
    "sign": sign,   # 常用关键字搜索匹配：1.sign,2.sign:,3.sign=,4.\bsign\b（\b表示单词边界，不存在字母字符） 根据可能的赋值形式
    "client": "fanyideskweb",
    "product": "webfanyi",
    "appVersion": "1.0.0",
    "vendor": "web",
    "pointParam": "client,mysticTime,product",
    "mysticTime": mysticTime,
    "keyfrom": "fanyi.web",
    "mid": "1",
    "screen": "1",
    "model": "1",
    "network": "wifi",
    "abtest": "0",
    "yduuid": "abcdefg"
}

resp = requests.post(url,headers=headers,data=data)
# print(resp.text)
# 得到返回的机密密文
string = resp.text
# 第一步解密，采用base64解密
new_res = string.replace('-','+').replace('_','/')
res = base64.b64decode(new_res.encode())

# 第二步解密，采用AES 126解密
key = [8, 20, 157, 167, 60, 89, 206, 98, 85, 91, 1, 233, 47, 52, 232, 56]
b_key = bytes(key)

iv = [210, 187, 27, 253, 232, 59, 56, 195, 68, 54, 99, 87, 183, 156, 174, 28]
b_iv = bytes(iv)

obj_cbc = AES.new(b_key, mode=AES.MODE_CBC, iv=b_iv)
cbc_res = obj_cbc.decrypt(res)
# print(cbc_res.decode())
# json_data = json.loads(cbc_res.decode())    # 有加载失败的可能性
json_str = cbc_res.decode()
# 使用 print(repr(data_str)) 打印原始字符串，检查是否有特殊字符
print(repr(json_str)) # 发现字符串末尾存在\r\r 这类数据，这是回车字符，影响loads解析。处理如下：

# 方法一，\r在字符串中间，采用replace
# json_data = json_data.replace('\r','')
# print(repr(json_data))
# json_data = json.loads(json_data)   # 成功解决报错

# 方法二， \r在字符串开头或末尾，采用str.strip()--去除首尾空格字符 与 str.rstrip()--去除尾部空白字符（（如空格、\t, \n, \r 等））
# json_data = json_data.strip()
# print(repr(json_data))
# json_data = json.loads(json_data)

# 方法三，针对末尾出现的所有未知字符，通过定位最后一个}进行截取
def json_parse(json_str):
    # 第一步，尝试移除尾部固定几个特殊字符'\x05\x00\t\r\n '
    cleaned_str = json_str.rstrip('\x05\x00\t\r\n ')
    try:
        json_data = json.loads(cleaned_str)
    except json.decoder.JSONDecodeError:
        # 用正则定位最后一个},进行字符串截取 
        last_brace = json_str.rfind('}')
        json_str = json_str[:last_brace + 1]   # 因为要保留}符号，所以截取位置+1
        json_data = json.loads(json_str)
    return json_data
json_data = json_parse(json_str)
translation_res = json_data['translateResult'][0][0]['tgt']
print(f'{i_value}的英文翻译为：{translation_res}')
